home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 6 / develop 6 code / TCP / NewsWatcher / NewsWatcher 2.0d15 source / source / open.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-30  |  8.5 KB  |  360 lines  |  [TEXT/KAHL]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     open.c
  4.  
  5.     This module handles creating and opening windows.
  6.     
  7.     Portions copyright © 1990, Apple Computer.
  8.     Portions copyright © 1993, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include "glob.h"
  13. #include "open.h"
  14. #include "drag.h"
  15. #include "ldef.h"
  16. #include "scroll.h"
  17. #include "util.h"
  18. #include "wind.h"
  19. #include "resize.h"
  20. #include "full.h"
  21.  
  22.  
  23.  
  24. /*      MyOffSet offsets a window so no two windows are at the same origin and the
  25.         windows do not hang off of the screen.
  26. */
  27.  
  28. static Rect *MyOffSet (Rect *theRect)
  29. {
  30.     WindowPtr wind;
  31.     Rect firstRect, bitsRect;
  32.         
  33.     firstRect = *theRect;
  34.     wind = FrontWindow();
  35.  
  36.     while (wind) {
  37.         if (wind->portBits.rowBytes & 0x8000 && wind->portBits.rowBytes & 0x4000) {
  38.             PixMapHandle pmap = ((CGrafPtr)wind)->portPixMap;
  39.             bitsRect = (**pmap).bounds;                     /* Color GrafPort */
  40.         } else {
  41.             bitsRect = wind->portBits.bounds;       /* Ordinary GrafPort */
  42.         }
  43.         if ((theRect->top == (-bitsRect.top)) && 
  44.             (theRect->left == (-bitsRect.left))) 
  45.         {
  46.             OffsetRect(theRect,25,25);
  47.             if (theRect->right > gDesktopExtent.right) {
  48.                 OffsetRect(&firstRect,0,27);
  49.                 *theRect = firstRect;
  50.             }
  51.             if (theRect->bottom > gDesktopExtent.bottom) {
  52.                 OffsetRect(&firstRect,27,0);
  53.                 *theRect = firstRect;
  54.             }
  55.             wind = FrontWindow();
  56.         } else {
  57.             wind = (WindowPtr) ((WindowPeek) wind)->nextWindow;
  58.         }
  59.     }
  60.         
  61.     if (theRect->top > gDesktopExtent.bottom)
  62.         theRect->top = gDesktopExtent.bottom - 10;
  63.     if (theRect->left > gDesktopExtent.right)
  64.         theRect->left = gDesktopExtent.right - 10;
  65.     if (theRect->bottom > gDesktopExtent.bottom && 
  66.         theRect->top < (gDesktopExtent.bottom-150))
  67.         theRect->bottom = gDesktopExtent.bottom;
  68.     if (theRect->right > gDesktopExtent.right && 
  69.         theRect->left < (gDesktopExtent.right-150))
  70.         theRect->right = gDesktopExtent.right;
  71.                 
  72.     return(theRect);
  73. }
  74.  
  75.  
  76. /*    CalcWindowHCoords calculates the horizontal coordinates of the various
  77.     components of a list window and records them in the TWindow struct
  78.     for the window. For subject windows it also (re)creates the collapsed
  79.     and expanded triangle polygons and saves handles to them in the TWindow
  80.     struct.
  81. */
  82.  
  83. void CalcWindowHCoords (WindowPtr wind)
  84. {
  85.     TWindow **info;
  86.     EWindowKind kind;
  87.     short w;
  88.     GrafPtr savePort;
  89.     FontInfo fontInfo;
  90.     short tHeight, tWidth, x;
  91.     long response;
  92.     
  93.     GetPort(&savePort);
  94.     SetPort(wind);
  95.     info = (TWindow**)GetWRefCon(wind);
  96.     kind = (**info).kind;
  97.     w = CharWidth('9');
  98.     if (kind == kUserGroup) {
  99.         (**info).groupNameHCoord = 6*w;
  100.         (**info).numUnreadHCoord = 4*w;
  101.     } else if (kind == kSubject) {
  102.         GetFontInfo(&fontInfo);
  103.         tWidth = fontInfo.ascent;
  104.         if ((tWidth & 1) == 1) tWidth--;
  105.         (**info).minusSignHCoord = ((tWidth - CharWidth('-')) >> 1) + 2;
  106.         (**info).threadCountHCoord = x = 3*w + tWidth;
  107.         (**info).checkHCoord = x = x + 2*w;
  108.         if ((**info).authorsShown) {
  109.             (**info).authorHCoord = x = x + 2*w;
  110.             (**info).authorWidth = 16*w;
  111.             (**info).subjectHCoord = x + 18*w;
  112.         } else {
  113.             (**info).subjectHCoord = (**info).authorHCoord = x = x + 2*w;
  114.         }
  115.         tHeight = tWidth >> 1; 
  116.         if ((**info).collapseTriangle != nil) KillPoly((**info).collapseTriangle);
  117.         if ((**info).expandTriangle != nil) KillPoly((**info).expandTriangle);
  118.         (**info).collapseTriangle = OpenPoly();
  119.             MoveTo(0,0);
  120.             LineTo(0,tWidth);
  121.             LineTo(tHeight,tHeight);
  122.             LineTo(0,0);
  123.         ClosePoly();
  124.         (**info).expandTriangle = OpenPoly();
  125.             MoveTo(0,0);
  126.             LineTo(tWidth,0);
  127.             LineTo(tHeight,tHeight);
  128.             LineTo(0,0);
  129.         ClosePoly();
  130.     }
  131.     SetPort(savePort);
  132. }
  133.  
  134.  
  135. /*    NewList makes a new list manager list for list windows */
  136.  
  137. static void NewList (WindowPtr wind)
  138. {
  139.     TWindow **info;
  140.     ListHandle theList;
  141.     Point thePt;
  142.     Rect listRect, sizeRect;
  143.     GrafPtr savePort;
  144.     short fontNum;
  145.     
  146.     info = (TWindow**)GetWRefCon(wind);
  147.     
  148.     SetPt(&thePt,0,0);
  149.     SetRect(&sizeRect,0,0,1,0);
  150.     SetRect(&listRect,
  151.         wind->portRect.left,
  152.         wind->portRect.top,
  153.         wind->portRect.right-15,
  154.         wind->portRect.bottom-15);
  155.     GetPort(&savePort);
  156.     SetPort(wind);
  157.     
  158.     GetFNum(gPrefs.listFont, &fontNum);
  159.     TextFont(fontNum);
  160.     TextSize(gPrefs.listSize);
  161.     theList = LNew(&listRect, &sizeRect, thePt, kLDEFProc,
  162.         wind, false, true, false, true);
  163.     (**theList).indent.h = 4;
  164.     (**theList).selFlags |= lNoNilHilite;
  165.     (**theList).refCon = (long)ListDefFunc;
  166.     (**theList).lActive = wind == FrontWindow();
  167.     (**info).theList = theList;
  168.     CalcWindowHCoords(wind);
  169.     SetPort(savePort);
  170. }
  171.  
  172.  
  173. /*    CalcPanelHeight calculates the panel height for an article or message 
  174.     window. 
  175. */
  176.  
  177. void CalcPanelHeight (WindowPtr wind)
  178. {
  179.     TWindow **info;
  180.     FontInfo fontInfo;
  181.     EWindowKind kind;
  182.     short panelHeight;
  183.     
  184.     info = (TWindow**)GetWRefCon(wind);
  185.     kind = (**info).kind;
  186.     if (kind != kArticle && kind != kMiscArticle && kind != kPostMessage &&
  187.         kind != kMailMessage) return;
  188.     GetFontInfo(&fontInfo);
  189.     if (kind == kMailMessage || kind == kPostMessage) {
  190.         panelHeight = fontInfo.ascent + fontInfo.descent + 9;
  191.         if (panelHeight < 34) panelHeight = 34;
  192.     } else {
  193.         panelHeight = 3 * (fontInfo.ascent + fontInfo.descent + 
  194.             fontInfo.leading) + 9;
  195.     }
  196.     (**info).panelHeight = panelHeight;
  197. }
  198.  
  199.  
  200. /*    NewText creates a new textedit record for article and message windows.
  201. */
  202.  
  203. static void NewText (WindowPtr wind)
  204. {
  205.     TWindow **info;
  206.     TEHandle theTE;
  207.     Rect theRect;
  208.     short fontNum;
  209.     
  210.     info = (TWindow**)GetWRefCon(wind);
  211.     
  212.     SetPort(wind);
  213.     
  214.     GetFNum(gPrefs.textFont,&fontNum);
  215.     TextFont(fontNum);
  216.     TextSize(gPrefs.textSize);
  217.     
  218.     CalcPanelHeight(wind);
  219.     
  220.     SetRect(&theRect,
  221.         wind->portRect.left,
  222.         wind->portRect.top + (**info).panelHeight,
  223.         wind->portRect.right-15,
  224.         wind->portRect.bottom-15);
  225.     InsetRect(&theRect,kTextMargin,kTextMargin);
  226.  
  227.     theTE = TENew(&theRect,&theRect);
  228.     SetClikLoop(AutoScroll,theTE);
  229.     
  230.     (**info).theTE = theTE;
  231. }
  232.  
  233.  
  234. /*    NewSendButton creates a new "Send" button control for message windows. */
  235.  
  236. static void NewSendButton (WindowPtr wind)
  237. {
  238.     TWindow **info;
  239.     Rect theRect;
  240.     
  241.     info = (TWindow**)GetWRefCon(wind);
  242.     theRect.right = wind->portRect.right - 5;
  243.     theRect.left = theRect.right-60;
  244.     theRect.top = ((**info).panelHeight - 24) >> 1;
  245.     theRect.bottom = theRect.top + 20;
  246.     NewControl(wind, &theRect, "\pSend", true, 0, 0, 0, 
  247.         pushButProc, kSendButton);
  248. }
  249.  
  250.  
  251. /*    MakeNewWindow is the low-level procedure to make a new NewsWatcher window.
  252.     Depending on what type is needed, the window will have different
  253.     features.
  254. */
  255.  
  256. WindowPtr MakeNewWindow (EWindowKind kind, Point topLeft, StringPtr title)
  257. {
  258.     
  259.     WindowPtr wind, front, behind;
  260.     TWindow **info;
  261.     Rect bounds;
  262.     short rightMark;
  263.     long response;
  264.         
  265.     switch (kind) {
  266.         case kFullGroup:
  267.         case kNewGroup:
  268.         case kUserGroup:
  269.             rightMark = topLeft.h+300;
  270.             break;
  271.         case kSubject:
  272.             rightMark = topLeft.h+400;
  273.             break;
  274.         case kArticle:
  275.         case kMiscArticle:
  276.         case kMailMessage:
  277.         case kPostMessage:
  278.             rightMark = topLeft.h+495;
  279.             break;
  280.     }
  281.  
  282.     SetRect(&bounds,
  283.         topLeft.h,
  284.         topLeft.v,
  285.         rightMark,
  286.         topLeft.v + kDefaultWindHeight);
  287.     front = FrontWindow();
  288.     behind = (IsStatusWindow(front)) ? front : (WindowPtr)-1;
  289.     if (gHasColorQD) {
  290.         wind = NewCWindow(nil, MyOffSet(&bounds), "\pUntitled", false,
  291.             zoomDocProc, behind, true, 0);
  292.     } else {
  293.         wind = NewWindow(nil,MyOffSet(&bounds), "\pUntitled", false,
  294.             zoomDocProc, behind, true, 0);
  295.     }
  296.     SetPort(wind);
  297.     SetWTitle(wind, title);
  298.     AddWindMenu(wind);
  299.     
  300.     info = (TWindow**)MyNewHandle(sizeof(TWindow));
  301.     if (MyMemErr() != noErr)
  302.         return nil;
  303.         
  304.     (**info).kind = kind;
  305.     SetWRefCon(wind, (long)info);
  306.     
  307.     switch (kind) {
  308.         case kFullGroup:
  309.         case kNewGroup:
  310.         case kUserGroup:
  311.             NewList(wind);
  312.             (**(**info).theList).lClikLoop = (ProcPtr)GroupListClickLoop;
  313.             (**info).strings = gGroupNames;
  314.             break;
  315.         case kSubject:
  316.             (**info).authorsShown = gPrefs.showAuthors;
  317.             NewList(wind);
  318.             break;
  319.         case kArticle:
  320.         case kMiscArticle:
  321.         case kPostMessage:
  322.         case kMailMessage:
  323.             NewText(wind);
  324.             MakeVScroller(wind);
  325.             if (kind == kPostMessage || kind == kMailMessage) 
  326.                 NewSendButton(wind);
  327.             break;
  328.     }
  329.     SizeContents(wind);
  330.  
  331.     return wind;
  332. }
  333.  
  334.  
  335. /*    NewUserGroupWindow creates a new user group window */
  336.  
  337. WindowPtr NewUserGroupWindow (StringPtr title, TGroup **groupArray, short numGroups)
  338. {
  339.     WindowPtr wind;
  340.     TWindow **info;
  341.     Point firstOffset;
  342.     Cell theCell;
  343.     
  344.     SetPt(&firstOffset, kOffLeft, kOffTop);
  345.     
  346.     info = (TWindow**) GetWRefCon(wind = 
  347.         MakeNewWindow(kUserGroup, firstOffset, title));
  348.     if (groupArray == nil) {
  349.         (**info).groupArray = (TGroup**)MyNewHandle(0);
  350.     } else {
  351.         (**info).groupArray = groupArray;
  352.         (**info).numGroups = numGroups;
  353.         MakeGroupList(numGroups, (**info).theList);
  354.         SetPt(&theCell, 0, 0);
  355.         LSetSelect(true, theCell, (**info).theList);
  356.     }
  357.     DoZoom(wind, inZoomOut);
  358.     return wind;
  359. }
  360.